DisqueのTTLとRetryについて
概要
TTLとRetry組み合わせた際の挙動がよくわかってなかったのでメモっておく。
Disqueはなんか分散ジョブキュー。
Disque
https://github.com/antirez/disque
使ってるクライアントは自作のDisquuun。
Disquuun
https://github.com/sassembla/Disquuun
TTL
Time To Live なのでDisque-serverに登録したジョブの生存時間。
Disqueの場合はAddJobコマンドのオプションでジョブ追加の都度指定する。
Disquuunの場合だと次のようなコードになる。
disquuun.AddJob("queueName", new byte[]{0,1,2}, 0, "TTL", 1);
TTLの単位はsecなので、これでDisque-server側にこのジョブは、ジョブがキュー"queueName"に追加されて1秒経つと消滅する。
ただし、デフォルトのDisqueの設定だと、こういったタイマーに関する分解能が10hz(秒間10回)程度になっているので、わりとやんわりとした動作になっている。
ちなみにTTLを指定しなかった場合のデフォルト値は 1day = 86400sec とか。
Retry
リトライ、なんかちゃんと向き合っていなかったのだけれど、
Retry値は、GetJobされたジョブが、再びキューに入るまでの時間を指定するパラメータになっている。
指定はDisquuunの場合だと次のようなコードになる。
disquuun.AddJob("queueName", new byte[]{0,1,2}, 0, "RETRY", 1);
この辺の挙動はテストケース書いたんで具体的にこうなるんだぜみたいな例がある。
https://github.com/sassembla/Disquuun/blob/master/DisquuunTest/Tests_1.cs#L64
Retryの値に関する仕様は以下のようになってるらしい。
・デフォルト値は5分
一度GetJobされてから5分経ったら、再装填が発生する。
・0ならば"最大で1回送付"モードになる
んでGetJobが発生したら実際にどうなるの?っていうと、これが面白かったので後述する。
・0より大きい数値ならば単位はsecで、この秒数が過ぎたら再装填が発生する
この値の指定と効果には特例があって、
TTLが指定してあり、かつ、TTL x 0.1(sec) < RETRY指定値(デフォの場合は5min)の場合、RETRY値はTTL x 0.1(sec) に指定される。
例えばTTLを5分にした場合、5x60sec(TTL) x 0.1 < 5x60sec(RETRY) なので、RETRY値は自動的に 5x60sec(TTL) x 0.1になる。
なにがなんでもRETRYさせたいらしい。まあ明示的に指定してるんだしな。
最大で1回送付 モードになるって実際にはどういう挙動なの?
ここまでで、TTLでジョブの寿命が、Retryでジョブの再装填が制御できることがわかった。
で、例えば次のような指定をした場合どうなるのか。
case1.Retry = 0
case2.TTL = 10sec
case3.Retry = 0 + TTL = 10sec
case1.Retry = 0
Retryが0なので、GetJobしたらackしないでも二度とキューに現れない。
ジョブ自体はどうなっちゃうんだろう?
var len0 = DisquuunDeserializer.Qlen(disquuun.Qlen("queueName").DEPRICATED_Sync());
このlen0は確かに0になる。
が、
var info = DisquuunDeserializer.Info(disquuun.Info().DEPRICATED_Sync());
var restJobCount = info.jobs.registered_jobs;
infoから取得するrestJobCountは、これなんと1件になる。
残っとるんかワレ。しかも二度と"queueName"には登らないだと、、、
別にRetry = 0時のみの特殊な挙動ではなくて、
Retryの値がなんであれ、例えばRetry指定をしてない場合は、
・5分経つまでキューの外で待つ(qlenは0を返す
・じゃあどこにいるの、っていうと、Infoでは見えるどこかにいる
という挙動になるみたいだ。
ちなみにRetry = 0だと、再装填は発生しない + TTL未指定なので、TTLデフォルトの1日が経過するのを待って死ぬ感じ。
case2.TTL = 10sec
Retryがデフォ5min -> TTLの10%より小さいので、RetryはTTLの10% = 1secになる。
つまりGetJobとかが発生すると、1秒で復帰してくる。
Disqueのフレームレートがデフォルト10hzなので、まあ10秒間の寿命の中できっちり10回再装填されることは無いと思うけれど、
なるほど1秒で再装填されるのか、、と思うと感慨深い。
case3.Retry = 0 + TTL = 10sec
というわけで、Retryを明示的に0にセットし、TTLを10secにした場合、
・ジョブは一度GetJobされたりすると、キューからは外れる
・Retry = 0なので二度とキューに再装填されない
・TTLが10secなので10秒したら死ぬ
というのが起こる。
以上。